/*
 * uart.h
 *
 *  Created on: Nov 13, 2013
 *      Author: PabloFR
 */

#ifndef UART_H_
#define UART_H_

#include "derivative.h"
/******************************************************************************************/
/*                   Macros that shall be configured for the system                       */
/******************************************************************************************/
#ifndef FALSE
	#define FALSE      0
#endif

#ifndef TRUE
	#define TRUE       1
#endif


/* UART C1 Register macros */
#define UART_8BITS 		0<<UART_C1_M_SHIFT
#define UART_9BITS		1<<UART_C1_M_SHIFT

#define UART_ENABLE_ODD_PARITY          (UART_C1_PE_MASK | UART_C1_PT_MASK)
#define UART_ENABLE_EVEN_PARITY         (UART_C1_PE_MASK)

/*UART C2 Register macros */

#define UART_TX_ENABLE 	TRUE
#define UART_RX_ENABLE 	TRUE


#if (UART_TX_ENABLE == TRUE)
#define UART_TIE_ENABLE		1<<UART_C2_TIE_SHIFT	
#define UART_TIE_DISABLE	0<<UART_C2_TIE_SHIFT	

#define UART_TCIE_ENABLE  	1<<UART_C2_TCIE_SHIFT
#define UART_TCIE_DISABLE	0<<UART_C2_TCIE_SHIFT
#endif


#if(UART_RX_ENABLE == TRUE)
#define UART_RIE_ENABLE 	1<<UART_C2_RIE_SHIFT
#define UART_RIE_DISABLE 	0<<UART_C2_RIE_SHIFT
#endif

#define UART_ILIE_ENABLE	1<<UART_C2_ILIE_SHIFT
#define UART_ILIE_DISABLE	0<<UART_C2_ILIE_SHIFT 

/*UART C3 Register macros */

#define UART_DATA_INV 	1<<UART_C3_TXINV_SHIFT
#define UART_DATA_NOINV 0<<UART_C3_TXINV_SHIFT

#define UART_HW_INT		1<<UART_C3_ORIE_SHIFT
#define UART_HW_NOINT	0<<UART_C3_ORIE_SHIFT

#define UART_NOISE_INT	 1<<UART_C3_NEIE_SHIFT
#define UART_NOISE_NOINT 0<<UART_C3_NEIE_SHIFT

#define UART_FRAME_INT	 1<<UART_C3_FEIE_SHIFT
#define UART_FRAME_NOINT 0<<UART_C3_FEIE_SHIFT

#define UART_PARITY_INT	  1<<UART_C3_PEIE_SHIFT
#define UART_PARITY_NOINT 0<<UART_C3_PEIE_SHIFT

/*UART C4 Register macros */

#define UART_10BITS 	1<<UART_C4_M10_SHIFT

#define UART_OSR		9

#define UART_Clock 		24000000			//24 Mhz output from PLL Clock 

#define UART_SBR(x)		UART_Clock/(x*(UART_OSR+1))



#define UART_PERIPHERAL                 0


#define UART_USE_PARITY_ERR_CALLBACK    FALSE 

#define UART_USE_RX_CALLBACK            TRUE

#if (UART_USE_RX_CALLBACK == TRUE)
	#define UART_RX_CALLBACK                UARTRxDataCallback
	extern void UART_RX_CALLBACK(void); 
#endif

#if (UART_USE_PARITY_ERR_CALLBACK == TRUE)
	#define UART_USE_PARITY_ERR_CALLBACK
	extern void UART_USE_PARITY_ERR_CALLBACK(void); 
#endif

/******************************************************************************************/
/* Defines and macros that should not be changed, are used to generate UART configuration */
/******************************************************************************************/
#if(UART_PERIPHERAL == 0)  
/**UART0 port is selected*/
	#define UART_BDH                     UART0_BDH
	#define UART_BDL                     UART0_BDL
	#define UART_C1                      UART0_C1
	#define UART_C2                      UART0_C2
	#define UART_S1                      UART0_S1
	#define UART_S2                      UART0_S2
	#define UART_C3                      UART0_C3
	#define UART_C4                      UART0_C4
	#define UART_D                       UART0_D
	#define UART_CONFIG_TX_PORT_CONTROL  PORTA_PCR2 = (2<<PORT_PCR_MUX_SHIFT)
	#define UART_CONFIG_RX_PORT_CONTROL  PORTA_PCR1 = (2<<PORT_PCR_MUX_SHIFT)

#elif(UART_PERIPHERAL == 1)
/**UART1 port is selected*/
	#define UART_BDH                     UART1_BDH
	#define UART_BDL                     UART1_BDL
	#define UART_C1                      UART1_C1
	#define UART_C2                      UART1_C2
	#define UART_S1                      UART1_S1
	#define UART_S2                      UART1_S2
	#define UART_C3                      UART1_C3
	#define UART_C4                      UART1_C4
	#define UART_D                       UART1_D
	#define UART_CONFIG_TX_PORT_CONTROL  PORTC_PCR4 = (2<<PORT_PCR_MUX_SHIFT)
	#define UART_CONFIG_RX_PORT_CONTROL  PORTC_PCR3 = (2<<PORT_PCR_MUX_SHIFT)
#elif (UART_PERIPHERAL == 2)
	#define UART_BDH                     UART2_BDH
	#define UART_BDL                     UART2_BDL
	#define UART_C1                      UART2_C1
	#define UART_C2                      UART2_C2
	#define UART_S1                      UART2_S1
	#define UART_S2                      UART2_S2
	#define UART_C3                      UART2_C3
	#define UART_C4                      UART2_C4
	#define UART_D                       UART2_D
#else
/**UART0 port is selected for default option*/
	#define UART_BDH                     UART0_BDH
	#define UART_BDL                     UART0_BDL
	#define UART_C1                      UART0_C1
	#define UART_C2                      UART0_C2
	#define UART_S1                      UART0_S1
	#define UART_S2                      UART0_S2
	#define UART_C3                      UART0_C3
	#define UART_C4                      UART0_C4
	#define UART_D                       UART0_D
	#define UART_CONFIG_TX_PORT_CONTROL  PORTD_PCR3 = (2<<PORT_PCR_MUX_SHIFT)
	#define UART_CONFIG_RX_PORT_CONTROL  PORTD_PCR2 = (2<<PORT_PCR_MUX_SHIFT)
#endif


#define UART_HW_IDLE                    ((UART_S1 & UART_S1_TC_MASK) && (!(UART_S2 & UART_S2_RAF_MASK)))
#define UART_ENABLE_EDGE_INTERRUPT    	(UART_BDH |= UART_BDH_RXEDGIE_MASK)
#define UART_DISABLE_EDGE_INTERRUPT   	(UART_BDH &= ~UART_BDH_RXEDGIE_MASK)
#define UART_CLEAR_EDGE_FLAG          	(UART_S2  |= UART_S2_RXEDGIF_MASK)

	
	
typedef enum
{
	UART_OK,
	UART_ERROR_NOT_IDLE,
	UART_ERROR_UART_INVALID_CONFIG,
	UART_ERROR_OUT_OF_RANGE,
	UART_ERROR_NO_DATA,
	UART_ERROR_FLAG_5,
	UART_ERROR_FLAG_6,
	UART_ERROR_FLAG_7
}__UART_ErrorValues__;


typedef enum
{
	UART_RX_OK,
	UART_TX_MSG,							//UART_TX_MSG = 0 means port ready 
	UART_TX_IN_PROGRESS,
	UART_RX_OVERRUN_ERROR,
	UART_NOISE_ERROR,
	UART_FRAMING_ERROR,
	UART_PARITY_ERROR,
	UART_RX_EDGE
}__UART_StatusFlags__;


/******************************************************************************************/
/*                     Function Prototypes and documentation                              */
/******************************************************************************************/

void UART_ConfigBaudRate(uint32_t Baudrate);

void UART_Config(void);

void UART0_ISR(void);

uint8_t UART_TRANSMIT_Message(uint8_t *Msg, uint16_t size);

#endif /* UART_KINETISL_H_ */
